home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / awksrc.zip / MISSING / STRTOD.C < prev    next >
C/C++ Source or Header  |  1992-06-16  |  2KB  |  121 lines

  1. /*
  2.  * strtod.c
  3.  *
  4.  * Stupid version of System V strtod(3) library routine.
  5.  * Does no overflow/underflow checking.
  6.  *
  7.  * A real number is defined to be
  8.  *    optional leading white space
  9.  *    optional sign
  10.  *    string of digits with optional decimal point
  11.  *    optional 'e' or 'E'
  12.  *        followed by optional sign or space
  13.  *        followed by an integer
  14.  *
  15.  * if ptr is not NULL a pointer to the character terminating the
  16.  * scan is returned in *ptr.  If no number formed, *ptr is set to str
  17.  * and 0 is returned.
  18.  *
  19.  * For speed, we don't do the conversion ourselves.  Instead, we find
  20.  * the end of the number and then call atof() to do the dirty work.
  21.  * This bought us a 10% speedup on a sample program at uunet.uu.net.
  22.  */
  23.  
  24. #if 0
  25. #include <ctype.h>
  26. #endif
  27.  
  28. extern double atof();
  29.  
  30. double
  31. strtod (s, ptr)
  32. register char *s;
  33. register char **ptr;
  34. {
  35.     double ret = 0.0;
  36.     char *start = s;
  37.     char *begin = NULL;
  38.     int success = 0;
  39.  
  40.     /* optional white space */
  41.     while (isspace(*s))
  42.         s++;
  43.  
  44.     /* optional sign */
  45.     if (*s == '+' || *s == '-') {
  46.         s++;
  47.         if (*(s-1) == '-')
  48.             begin = s - 1;
  49.         else
  50.             begin = s;
  51.     }
  52.  
  53.     /* string of digits with optional decimal point */
  54.     if (isdigit(*s) && ! begin)
  55.         begin = s;
  56.  
  57.     while (isdigit(*s)) {
  58.         s++;
  59.         success++;
  60.     }
  61.  
  62.     if (*s == '.') {
  63.         if (! begin)
  64.             begin = s;
  65.         s++;
  66.         while (isdigit(*s))
  67.             s++;
  68.         success++;
  69.     }
  70.  
  71.     if (s == start || success == 0)        /* nothing there */
  72.         goto out;
  73.  
  74.     /*
  75.       *    optional 'e' or 'E'
  76.      *        followed by optional sign or space
  77.      *        followed by an integer
  78.      */
  79.  
  80.     if (*s == 'e' || *s == 'E') {
  81.         s++;
  82.  
  83.         /* XXX - atof probably doesn't allow spaces here */
  84.         while (isspace(*s))
  85.             s++;
  86.  
  87.         if (*s == '+' || *s == '-')
  88.             s++;
  89.  
  90.         while (isdigit(*s))
  91.             s++;
  92.     }
  93.  
  94.     /* go for it */
  95.     ret = atof(begin);
  96.  
  97. out:
  98.     if (! success)
  99.         s = start;    /* in case all we did was skip whitespace */
  100.  
  101.     if (ptr)
  102.         *ptr = s;
  103.  
  104.     return ret;
  105. }
  106.  
  107. #ifdef TEST
  108. main (argc, argv)
  109. int argc;
  110. char **argv;
  111. {
  112.     double d;
  113.     char *p;
  114.  
  115.     for (argc--, argv++; argc; argc--, argv++) {
  116.         d = strtod (*argv, & p);
  117.         printf ("%lf [%s]\n", d, p);
  118.     }
  119. }
  120. #endif
  121.